home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: mgleason@cse.unl.edu (Mike Gleason)
- Subject: v23i103: ison - be informed when a user logs on, Part01/01
- Message-ID: <1991Oct22.033547.2041@sparky.imd.sterling.com>
- X-Md4-Signature: 4e5948f888ff87db821cafeb26e8e06b
- Date: Tue, 22 Oct 1991 03:35:47 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: mgleason@cse.unl.edu (Mike Gleason)
- Posting-number: Volume 23, Issue 103
- Archive-name: ison/part01
- Environment: UNIX
-
- IsOn's purpose is to let you know when someone logs on. You could always sit
- there at your terminal typing 'finger' or 'who' every 5 minutes, but that's
- boring and unproductive. IsOn makes this easy. If you wanted to know the
- instant I logged on, all it would take is a simple:
-
- ison mgleason@cse.unl.edu &
-
- When I do log on, ison would respond:
-
- ** mgleason logged in since Wed Oct 16 02:19:33 1991
-
- IsOn lowers it's priority automatically, so it takes very little CPU, and
- spares you the trouble of remembering to use 'nice.' For remote addresses
- (those in dude@machine.domain format) the 'finger' utility is used, or for
- a user on the same machine that you are on, IsOn will simply walk the 'utmp'
- file.
-
- Enjoy!
- --mike gleason = mgleason@cse.unl.edu
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: ison.c ison.readme
- # Wrapped by mgleason@cse on Wed Oct 16 06:00:19 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'ison.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ison.c'\"
- else
- echo shar: Extracting \"'ison.c'\" \(9646 characters\)
- sed "s/^X//" >'ison.c' <<'END_OF_FILE'
- X/* IsOn... Copyright 1990, 1991 NCEMRSoft. Use at your own risk!
- X - v1.0 : 1990 : Phil Dietz, NCEMRSoft.
- X : Original release.
- X - v2.0 : 05 Feb 91 : Phil Dietz, NCEMRSoft.
- X : Added 'finger'ing remote machines.
- X : Names and searches are now case insensitive.
- X - v3.0 : 04 Aug 91 : Mike Gleason, NCEMRSoft.
- X : Complete rewrite, using unix system calls.
- X : Remote addresses are recognized automatically.
- X : IsOn nice's (lowers it's priority) itself.
- X : Remote commands are exec'd instead of subshelled.
- X : Uses handy getopt() function.
- X : Added -f option, in case you don't have finger,
- X : our finger flags don't work, or want to try
- X : it rwho, etc.
- X : Added -d debugging option, so you can watch
- X : ison's progress. This is also useful if you
- X : want to log to a file.
- X
- X To compile: "cc -O ison.c -o ison" */
- X
- X#define VERSION_STR "Version 3.0 (04 Aug 91)"
- X
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <utmp.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#define SZ(expr) ((size_t) (expr))
- X#define DSLEEP 10 /* seconds to delay between iterations */
- X#define DDEBUG 0 /* prints stuff if > 0 */
- X#define DMAXITER -1L /* loop forever until we find the guy */
- X#define DCOMMAND NULL /* command line to do when user is found */
- X#define DFINGER "finger -fq"
- X
- X#ifndef INDEX
- X# ifdef _SYSTYPE_SYSV
- X# define INDEX strchr
- X# else /* bsd */
- X# define INDEX index
- X# endif
- X#endif
- X
- Xextern size_t fread();
- Xextern FILE *fopen(), *popen();
- Xextern char *INDEX();
- Xint strnicmp(), Nice(), Utmp(), Finger();
- X
- Xmain(argc, argv)
- X int argc;
- X char **argv;
- X{
- X int sleep_sec = DSLEEP;
- X int debug = DDEBUG;
- X long maxiter = DMAXITER;
- X int notfound, flag;
- X char *username, hostname[64], *cp;
- X char *fingercmd = DFINGER;
- X char *cmd = DCOMMAND;
- X time_t logontime;
- X extern int getopt(), optind; /* getopt() stuff */
- X extern char *optarg; /* getopt() stuff */
- X
- X if (argc <= 1)
- X usage (argv[0], fingercmd);
- X
- X while ((flag = getopt (argc, argv, "dvs:p:i:f:")) != EOF)
- X switch(flag) {
- X case 'd':
- X case 'v': /* debug mode, verbose mode, same thing */
- X debug++;
- X break;
- X case 's':
- X cmd = optarg;
- X break;
- X case 'p':
- X sleep_sec = atoi (optarg);
- X if (sleep_sec < 0) sleep_sec = DSLEEP;
- X break;
- X case 'i':
- X maxiter = (long) atol (optarg);
- X break;
- X case 'f':
- X fingercmd = optarg;
- X break;
- X default: usage (argv[0], fingercmd);
- X }
- X username = argv[optind];
- X if (username == NULL || strlen(username) == SZ(0))
- X usage (argv[0], fingercmd); /* no user specified! */
- X
- X /* lower our process' priority (nice) */
- X if (Nice (getpid ()))
- X perror ("Nice");
- X
- X /* Check the username for an @, which would suggest that it is
- X a domain-style address. */
- X if ((cp = INDEX (username, (int)'@')) != NULL) {
- X strcpy (hostname, cp); /* @machine.domain.xxx */
- X *cp = '\0'; /* shorten address down to just username */
- X notfound = Finger (username, sleep_sec, maxiter, argv[0],
- X hostname, fingercmd, debug);
- X time(&logontime);
- X } else
- X notfound = Utmp (username, sleep_sec, maxiter, argv[0],
- X debug, &logontime);
- X
- X /* See if the user was found. If not, explain why not. */
- X if (notfound != 0) {
- X if (notfound > 0) /* maxiter encoutered */
- X (void) fprintf (stderr, "## %s is not on.\n", username);
- X else (void) fprintf (stderr,
- X "## %s: cannot go on because of errors.\n", argv[0]);
- X } else {
- X /* When we get here, the user we're looking for was detected. */
- X (void) fprintf (stderr, "** %s%s logged in since %s",
- X#ifdef NO_BEEP
- X "",
- X#else
- X "\007", /* Control-G, the ascii BEL character */
- X#endif
- X username, ctime(&logontime));
- X if (cmd != NULL) {
- X /* Run a command (script) if the user requested to. */
- X (void) execlp ("/bin/sh", "sh", "-c", cmd, NULL);
- X (void) perror (cmd);
- X }
- X }
- X exit (notfound);
- X} /* main */
- X
- X
- X
- X
- Xint Utmp(username, sleep_sec, maxiter, progname, debug, tyme)
- X char *username, *progname;
- X int sleep_sec, debug;
- X long maxiter;
- X time_t *tyme;
- X{
- X struct utmp info;
- X FILE *in;
- X register int not_on = 1, iter = 1;
- X register size_t unamelen = strlen (username);
- X
- X /* Open the utmp file, which is a list of all logged on users. */
- X if ((in = fopen (UTMP_FILE, "r")) == NULL) {
- X (void) perror (UTMP_FILE);
- X return (1);
- X }
- X
- X do {
- X if (debug > 0) {
- X time(tyme);
- X (void) printf("## %s: checking utmp (try #%d) at %s",
- X progname, iter, ctime(tyme));
- X }
- X
- X /* Reset the utmp file and re-read it. */
- X (void) rewind (in);
- X
- X /* Cycle through all 'users' logged in. */
- X while (not_on && (fread (&info, SZ(sizeof (info)), SZ(1), in)) == SZ(1)) {
- X not_on = strnicmp(info.ut_name, username, unamelen);
- X if (debug > 1 && *info.ut_name) {
- X info.ut_name[8] = '\0';
- X printf("%s\n", info.ut_name);
- X }
- X }
- X
- X /* Delay a little so we won't hog the CPU */
- X if (not_on) {
- X if (maxiter > 0 && ++iter > maxiter) {
- X not_on = 1; break;
- X }
- X (void) sleep (sleep_sec);
- X }
- X } while (not_on);
- X
- X *tyme = info.ut_time; /* will hold garbage if user not found! */
- X (void) fclose (in);
- X return (not_on);
- X} /* Utmp */
- X
- X
- X
- X
- Xint Finger(username, sleep_sec, maxiter, progname, hostname, fingercmd, debug)
- X char *username, *progname, *hostname, *fingercmd;
- X int sleep_sec, debug;
- X long maxiter;
- X{
- X FILE *in;
- X register int not_on = 1, iter = 1, piperesult;
- X register size_t unamelen = strlen (username);
- X extern int errno;
- X char buf[160], pipename[128];
- X time_t now;
- X
- X strcpy(pipename, fingercmd);
- X strcat(pipename, " ");
- X if (strnicmp("finger", fingercmd, SZ(6)) != 0)
- X hostname++; /* Skip the @ sign if it's not finger! */
- X strcat(pipename, hostname);
- X
- X do {
- X if (debug > 0) {
- X time(&now);
- X (void) printf("## %s: %s (try #%d), at %s",
- X progname, pipename, iter, ctime(&now));
- X }
- X
- X if ((in = popen (pipename, "r")) == NULL) {
- X perror (fingercmd);
- X not_on = -errno;
- X break;
- X }
- X
- X /* Cycle through all 'users' logged in. */
- X while (not_on && fgets (buf, (int)sizeof(buf), in) != NULL) {
- X if (debug > 1) printf(buf);
- X not_on = strnicmp(buf, username, unamelen);
- X }
- X
- X piperesult = pclose(in); /* close pipe */
- X if (piperesult && not_on) {
- X not_on = (piperesult > 0) ? -piperesult : piperesult;
- X break;
- X }
- X
- X /* Delay a little so we won't hog the CPU */
- X if (not_on) {
- X if (maxiter > 0 && ++iter > maxiter) {
- X not_on = 1; break;
- X }
- X (void) sleep (sleep_sec);
- X }
- X } while (not_on);
- X return (not_on);
- X} /* Finger */
- X
- X
- X
- Xstrnicmp(a, b, n)
- X char *a, *b;
- X register size_t n;
- X{
- X register int i;
- X
- X for ( ; tolower(*a) == tolower(*b) && n-- > 0; a++, b++)
- X if (*a == '\0')
- X return (0); /* equal */
- X return (n <= 0 ? 0 : tolower(*a) - tolower(*b));
- X}
- X
- X
- X
- X
- Xusage(progname, fingercmd)
- X char *progname, *fingercmd;
- X{
- X (void) fprintf (stderr,
- X"usage: %s [-p N] [-i N] [-s cmd] [-f cmd] [-d] username &\n\
- X\t-p N : Delay 'N' seconds between iterations (default 10).\n\
- X\t-i N : Give up after 'N' iterations (default is infinity)\n\
- X\t-s cmd : Command to execute when user is found (i.e. \"talk username\")\n\
- X\t-f cmd : Command to execute for remote addresses (def: \"%s\")\n\
- X\t-d : Debugging mode. More d's, more stuff.\n\n\
- X%s by Phil Dietz & Mike Gleason, NCEMRSoft.\n\
- XThis is TuitionWare. Please send a buck to help us through school!\n\
- X\tPhil Dietz, Box 306, Yutan, NE 68073, USA... Thanks!\n\n",
- X progname, fingercmd, VERSION_STR);
- X exit (1);
- X} /* usage */
- X
- X
- X
- X
- X#include <sys/resource.h>
- X#define DEFAULT_NICE_INCREMENT 10
- X
- Xint Nice(pid)
- X pid_t pid;
- X{
- X extern int errno;
- X register int priority;
- X
- X#ifndef NOT_NICE /* #define it if you don't want to be nice'd */
- X errno = 0; /* clear it, since priority can be -1! */
- X priority = getpriority(PRIO_PROCESS, pid);
- X if (errno == 0) {
- X priority += DEFAULT_NICE_INCREMENT;
- X if (priority > PRIO_MAX)
- X priority = PRIO_MAX;
- X (void) setpriority(PRIO_PROCESS, pid, priority);
- X }
- X#endif
- X return (errno);
- X} /* Nice */
- X
- X/* eof */
- END_OF_FILE
- if test 9646 -ne `wc -c <'ison.c'`; then
- echo shar: \"'ison.c'\" unpacked with wrong size!
- fi
- # end of 'ison.c'
- fi
- if test -f 'ison.readme' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ison.readme'\"
- else
- echo shar: Extracting \"'ison.readme'\" \(764 characters\)
- sed "s/^X//" >'ison.readme' <<'END_OF_FILE'
- XIsOn's purpose is to let you know when someone logs on. You could always sit
- Xthere at your terminal typing 'finger' or 'who' every 5 minutes, but that's
- Xboring and unproductive. IsOn makes this easy. If you wanted to know the
- Xinstant I logged on, all it would take is a simple:
- X
- X ison mgleason@cse.unl.edu &
- X
- XWhen I do log on, ison would respond:
- X
- X ** mgleason logged in since Wed Oct 16 02:19:33 1991
- X
- XIsOn lowers it's priority automatically, so it takes very little CPU, and
- Xspares you the trouble of remembering to use 'nice.' For remote addresses
- X(those in dude@machine.domain format) the 'finger' utility is used, or for
- Xa user on the same machine that you are on, IsOn will simply walk the 'utmp'
- Xfile.
- X
- XEnjoy!
- X--mike gleason = mgleason@cse.unl.edu
- X
- END_OF_FILE
- if test 764 -ne `wc -c <'ison.readme'`; then
- echo shar: \"'ison.readme'\" unpacked with wrong size!
- fi
- # end of 'ison.readme'
- fi
- echo shar: End of shell archive.
- exit 0
- --
- ______________________________________________________________________________
- mike gleason mgleason@cse.unl.edu NCEMRSoft, baby!
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-